package com.swensen.game.editor.data;

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.Timer;

import com.swensen.game.Board.FocusSprite;
import com.swensen.game.data.GameState;
import com.swensen.game.data.Tile;
import com.swensen.game.data.TileSet;

/**
 * The Class Cursor.
 */
public class Cursor implements FocusSprite {
	
	/**
	 * The Class TileTimer.
	 */
	private class TileTimer implements ActionListener {

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			changeTile();
			cursorTimer.setDelay((int)Math.max(cursorTimer.getDelay() / 2.0, 20.0));
		}
	}
	
	/** The Constant DELAY. */
	private static final int DELAY = 500;

	/** The cursor timer. */
	private Timer cursorTimer = new Timer(DELAY, new TileTimer());
	
	/** The dtile. */
	int dtile = 0;
	
	/** The dx. */
	int dx = 0;
	
	/** The dy. */
	int dy = 0;
	
	/** The position. */
	private Point position = new Point(0,0);
	
	/**
	 * Align.
	 *
	 * @param p the p
	 */
	public void align(Point p) {
		position = p;
	}
	
	/**
	 * Change tile.
	 */
	private void changeTile() {
		synchronized(this) {
			GameState.INSTANCE.<EditorBoardData>getBoardData().moveCurrentTile(dtile);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#getImage()
	 */
	@Override
	public BufferedImage getImage() {
		synchronized(this) {
			Tile tile = GameState.INSTANCE.<EditorBoardData>getBoardData().getCurrentTile();
			TileSet set = GameState.getCurrentTileSet();
			return tile == null || set == null ? null : set.getImage(tile.getImageData());
		}
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#keyPressed(java.awt.event.KeyEvent)
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
			case KeyEvent.VK_LEFT:
				dx = -1;
				break;
			case KeyEvent.VK_RIGHT:
				dx = 1;
				break;
			case KeyEvent.VK_UP:
				dy = -1;
				break;
			case KeyEvent.VK_DOWN:
				dy = 1;
				break;
			case KeyEvent.VK_COMMA:
				dtile = -1;
				changeTile();
				cursorTimer.setDelay(DELAY);
				cursorTimer.start();
				break;
			case KeyEvent.VK_PERIOD:
				dtile = 1;
				changeTile();
				cursorTimer.setDelay(DELAY);
				cursorTimer.start();
				break;
		}
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#keyReleased(java.awt.event.KeyEvent)
	 */
	@Override
	public void keyReleased(KeyEvent e) {
		switch (e.getKeyCode()) {
			case KeyEvent.VK_LEFT:
			case KeyEvent.VK_RIGHT:
				dx = 0;
				break;
			case KeyEvent.VK_UP:
			case KeyEvent.VK_DOWN:
				dy = 0;
				break;
			case KeyEvent.VK_COMMA:
			case KeyEvent.VK_PERIOD:
				cursorTimer.stop();
				break;
		}
	}

	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#move(com.swensen.game.editor.data.Bounds)
	 */
	@Override
	public void move(Bounds bounds) {
		if ((dx < 0. && position.x >= bounds.getMinX() + Tile.TILE_SIZE) ||
			(dx > 0 && position.x < bounds.getMaxX() - Tile.TILE_SIZE)) {
			position.translate(dx * Tile.TILE_SIZE, 0);
		}
		if ((dy < 0 && position.y >= bounds.getMinY() + Tile.TILE_SIZE) ||
			(dy > 0 && position.y < bounds.getMaxY() - Tile.TILE_SIZE)) {
			position.translate(0, dy * Tile.TILE_SIZE);
		}
	}

	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#tileX()
	 */
	@Override
	public int tileX() {
		return position.x / Tile.TILE_SIZE;
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#tileY()
	 */
	@Override
	public int tileY() {
		return position.y / Tile.TILE_SIZE;
	}

	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#translate(int, int)
	 */
	@Override
	public void translate(int x, int y) {
		position.translate(x, y);
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#x()
	 */
	@Override
	public int x() {
		return position.x;
	}
	
	/* (non-Javadoc)
	 * @see com.swensen.game.data.Sprite#y()
	 */
	@Override
	public int y() {
		return position.y;
	}
}
